package infra;

import business.CDocument;
import business.AbstractDocument;
import business.JavaDocument;
import business.TxtDocument;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

public class FileDocumentDAO implements InterfaceDocumentDAO
{

    // Constants
    private final String PATH = "Documents";
    
    private final String JAVA_EXTENSION = ".java";
    private final String C_EXTENSION = ".c";
    private final String TXT_EXTENSION = ".txt";
    
    private final Charset ENCODING = StandardCharsets.UTF_8;

    //Singleton instance
    private static FileDocumentDAO instance;

    private FileDocumentDAO()
    {
    }

    public FileDocumentDAO getInstance()
    {
        if (this.instance == null)
        {
            instance = new FileDocumentDAO();
        }
        return this.instance;
    }

    /**
     * Save a new AbstractDocument
     *
     * @param document The document you want to save
     * @param subPath
     * @return
     * @throws IOException
     */
    @Override
    public boolean createDocument(AbstractDocument document, String subPath) throws IOException
    {
        File docFile = new File(PATH + File.pathSeparator + subPath + File.pathSeparator + document.getTitle());
        if (docFile.exists())
        {
            return false; //arquivo já existe
        }
        docFile.createNewFile();

        Path path = Paths.get(PATH + File.pathSeparator + subPath + File.pathSeparator + document.getTitle());
        try (BufferedWriter writer = Files.newBufferedWriter(path, ENCODING))
        {
            writer.write(document.getSource());
            return true;
        }
        catch (IOException erro)
        {
            return false;
        }
    }

    @Override
    public AbstractDocument retrieveDocument(String title, String subPath) throws IOException
    {
        File docFile = new File(PATH + File.separator + subPath + File.separator + title);
        if (!docFile.exists())
        {
            throw new IOException("Arquivo não existe");
        }
        Path path = Paths.get(PATH + File.separator + subPath + File.separator + title);
        String source = "";
        try (BufferedReader reader = Files.newBufferedReader(path, ENCODING))
        {
            String line = null;
            while ((line = reader.readLine()) != null)
            {
                source += line;
            }
        }
        switch(title.split(".")[1])
        {
            case JAVA_EXTENSION: return new JavaDocument(title, source);
            case C_EXTENSION: return new CDocument(title, source);
            case TXT_EXTENSION: return new TxtDocument(title, source);
        }
        return null;
    }

    @Override
    public boolean updateDocument(AbstractDocument updatedDoc, String title, String subPath) throws IOException
    {
        File docFile = new File(PATH + File.separator + subPath + File.separator + title);
        if (!docFile.exists())
        {
            return false; //arquivo não existe
        }

        Path path = Paths.get(PATH + File.separator + subPath + File.separator + title);
        try (BufferedWriter writer = Files.newBufferedWriter(path, ENCODING))
        {
            writer.write(updatedDoc.getSource());
            return true;
        }
        catch (IOException erro)
        {
            return false;
        }
    }

    @Override
    public boolean deleteDocument(AbstractDocument doc, String subPath)
    {
        File docFile = new File(PATH + File.separator + subPath + File.separator + doc.getTitle());
        if (!docFile.exists())
        {
            return false; //arquivo não existe
        }
        docFile.delete();
        return true;
    }
}
